﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Web.Services.Protocols;

namespace WoChu.CF.BaseFrame.Util
{
    /// <summary>
    /// RfAppException 发生非致命应用程序异常时产生的错误。
    /// </summary>
    public class RfAppException : ApplicationException
    {

        #region 变量定义...
        private static readonly string ControllableExceptionElementName = "Exception";
        private static readonly string ExceptionMessageNodeName = "Message";
        private static readonly string ExceptionMessageLevelNodeName = "MessageLevel";
        private static readonly string ExceptionMessageCodeNodeName = "MessageCode";

        private SysMessageLevel _MsgLever;
        private int _ErrorCode;

        #endregion 变量定义...

        #region 构造函数...
        /// <summary>
        /// 构造函数...
        /// </summary>
        /// <param name="pMsg">抛出异常的信息</param>
        protected RfAppException(string clientMsg)
            : this(clientMsg, SysMessageLevel.SysErrInfo)
        {
        }
        /// <summary>
        /// 构造函数...
        /// </summary>
        /// <param name="pMsg"></param>
        /// <param name="pMsgLever"></param>
        protected RfAppException(string clientMsg, SysMessageLevel msgLever)
            : this(clientMsg, msgLever, -1)
        {
        }
        /// <summary>
        /// 构造函数...
        /// </summary>
        /// <param name="pMsg">抛出异常的信息</param>
        /// <param name="pMsgLever">异常信息的类型等级</param>
        protected RfAppException(string clientMsg, SysMessageLevel msgLever, int errorCode)
            : base(clientMsg)
        {

            _MsgLever = msgLever;
            _ErrorCode = errorCode;
            TraceEx.Write(clientMsg, msgLever);

        }
        /// <summary>
        ///  构造函数...
        /// </summary>
        /// <param name="clientMsg"></param>
        /// <param name="msgLever"></param>
        /// <param name="innerException"></param>
        protected RfAppException(string clientMsg, SysMessageLevel msgLever, Exception innerException)
            : base(clientMsg, innerException)
        {

            _MsgLever = msgLever;
            TraceEx.Write(clientMsg, msgLever);
        }
        #endregion 构造函数...

        #region 创建异常处理相关...
        /// <summary>
        /// 创建异常
        /// </summary>
        /// <param name="message"></param>
        /// <param name="msgLever"></param>
        /// <returns></returns>
        public static RfAppException CreateAppException(string message, SysMessageLevel msgLever)
        {
            return new RfAppException(message, msgLever);
        }
        /// <summary>
        /// 创建异常。
        /// </summary>
        /// <param name="ex"></param>
        /// <param name="msgLever"></param>
        /// <returns></returns>
        public static RfAppException CreateAppException(Exception ex, SysMessageLevel msgLever)
        {
            if (ex is RfAppException)
            {
                return ex as RfAppException;
            }
            else
            {
                RfAppException aex = new RfAppException(ex.Message, msgLever, ex);
                return aex;
            }
        }
        /// <summary>
        /// 创建显示给用户的消息。
        /// </summary>
        /// <param name="message"></param>
        /// <param name="pars"></param>
        /// <returns></returns>
        public static RfAppException CreateDisplayToUser(string message, params string[] pars)
        {
            return new RfAppException(string.Format(message, pars), SysMessageLevel.DisplayToUser);
        }
        #endregion 创建异常处理相关...

        #region 静态方法...
        /// <summary>
        ///把WebService 传过来的异常转换为可操作的异常。
        /// </summary>
        /// <param name="ex"></param>
        /// <returns></returns>
        public static RfAppException ConvertAppException(Exception ex)
        {
            SoapException se = ex as SoapException;
            string message = string.Empty;
            int errorCode = -1;
            SysMessageLevel messageLevel = SysMessageLevel.SysErrInfo;
            if (se == null)
            {
                return RfAppException.CreateAppException(ex, SysMessageLevel.OtherSysInfo);
            }

            XmlDocument doc = null;
            try
            {
                doc = new XmlDocument();
                doc.LoadXml(se.Detail.OuterXml);
            }
            catch { }
            if (doc == null)
            {
                return RfAppException.CreateAppException(ex, SysMessageLevel.WebService);
            }
            XmlNodeList nodeList = doc.GetElementsByTagName(ControllableExceptionElementName);
            if (nodeList.Count == 0)
            {
                return RfAppException.CreateAppException(ex, SysMessageLevel.WebService);
            }
            XmlNode rootNode = nodeList[0];

            foreach (XmlNode childNode in rootNode.ChildNodes)
            {
                if (string.Compare(childNode.Name, ExceptionMessageNodeName, true) == 0)
                {
                    message = childNode.InnerText;
                    continue;
                }
                if (string.Compare(childNode.Name, ExceptionMessageLevelNodeName, true) == 0)
                {
                    try
                    {
                        messageLevel = (SysMessageLevel)Enum.Parse(typeof(SysMessageLevel), childNode.InnerText, true);
                    }
                    catch { }
                    continue;
                }
                if (string.Compare(childNode.Name, ExceptionMessageCodeNodeName, true) == 0)
                {
                    try
                    {
                        errorCode = int.Parse(childNode.InnerText);
                    }
                    catch { }
                    continue;
                }
            }
            return new RfAppException(message, messageLevel, errorCode);
        }
        #endregion 静态方法...

        #region Public 属性...

        /// <summary>
        /// 异常消息的类型
        /// </summary>
        public SysMessageLevel MsgLever
        {
            get
            {
                return _MsgLever;
            }
            set
            {
                _MsgLever = value;
            }
        }
        /// <summary>
        /// 产生异常的错误编码数值。
        /// </summary>
        public int ErrorCode
        {
            get
            {
                return _ErrorCode;
            }
            set
            {
                _ErrorCode = value;
            }
        }
        #endregion Public 属性...
    }
}
